<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>事件(event) | haijd</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  <meta name="keywords" content="c#学习笔记" />
  
  
  
  
  <meta name="description" content="c#事件">
<meta name="keywords" content="c#学习笔记">
<meta property="og:type" content="article">
<meta property="og:title" content="事件(Event)">
<meta property="og:url" content="http://www.hais2.com/2015/05/21/c#-Event/index.html">
<meta property="og:site_name" content="haijd">
<meta property="og:description" content="c#事件">
<meta property="og:locale" content="default">
<meta property="og:image" content="http://www.hais2.com/image/cSharp/cSharp53.png">
<meta property="og:image" content="http://www.hais2.com/image/cSharp/cSharp54.png">
<meta property="og:image" content="http://www.hais2.com/image/cSharp/cSharp55.png">
<meta property="og:image" content="http://www.hais2.com/image/cSharp/cSharp56.png">
<meta property="og:image" content="http://www.hais2.com/image/cSharp/cSharp57.png">
<meta property="og:image" content="http://www.hais2.com/image/cSharp/cSharp58.png">
<meta property="og:updated_time" content="2017-08-02T15:22:33.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="事件(Event)">
<meta name="twitter:description" content="c#事件">
<meta name="twitter:image" content="http://www.hais2.com/image/cSharp/cSharp53.png">
  
    <link rel="alternate" href="/atom.xml" title="haijd" type="application/atom+xml">
  
  <link rel="icon" href="/css/images/favicon.ico">
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link href="https://fonts.googleapis.com/css?family=Open+Sans|Montserrat:700" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic" rel="stylesheet" type="text/css">
  <link href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
  <style type="text/css">
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/9749f0/00000000000000000001008f/27/l?subset_id=2&fvd=n5) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/90cf9f/000000000000000000010091/27/l?subset_id=2&fvd=n7) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/8a5494/000000000000000000013365/27/l?subset_id=2&fvd=n4) format("woff2");font-weight:lighter;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/d337d8/000000000000000000010095/27/l?subset_id=2&fvd=i4) format("woff2");font-weight:400;font-style:italic;}</style>
    
  <link rel="stylesheet" id="athemes-headings-fonts-css" href="//fonts.googleapis.com/css?family=Yanone+Kaffeesatz%3A200%2C300%2C400%2C700&amp;ver=4.6.1" type="text/css" media="all">
  <link rel="stylesheet" href="/css/style.css">

  <script src="/js/jquery-3.1.1.min.js"></script>

  <!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="/css/bootstrap.css" >
  <link rel="stylesheet" href="/css/hiero.css" >
  <link rel="stylesheet" href="/css/glyphs.css" >
  
    <link rel="stylesheet" href="/css/vdonate.css" >
  

</head>

<script>
var themeMenus = {};

  themeMenus["/"] = "Home"; 

  themeMenus["/archives"] = "Archives"; 

  themeMenus["/categories"] = "Categories"; 

  themeMenus["/tags"] = "Tags"; 

  themeMenus["/about"] = "About"; 

</script>


  <body data-spy="scroll" data-target="#toc" data-offset="50">


  <header id="allheader" class="site-header" role="banner">
  <div class="clearfix container">
      <div class="site-branding">

          <h1 class="site-title">
            
              <a href="/" title="haijd" rel="home"> haijd </a>
            
          </h1>

          
            <div class="site-description">Stay Hungry,Stay Foolish</div>
          
            
          <nav id="main-navigation" class="main-navigation" role="navigation">
            <a class="nav-open">Menu</a>
            <a class="nav-close">Close</a>
            <div class="clearfix sf-menu">

              <ul id="main-nav" class="nmenu sf-js-enabled">
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/">Home</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/archives">Archives</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/categories">Categories</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/tags">Tags</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663"> <a class="" href="/about">About</a> </li>
                    
              </ul>
            </div>
          </nav>


      </div>
  </div>
</header>




  <div id="container">
    <div id="wrap">
            
      <div id="content" class="outer">
        
          <section id="main" style="float:none;"><article id="post-c#-Event" style="width: 66%; float:left;" class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="clearfix post-1016 post type-post status-publish format-standard has-post-thumbnail hentry category-template-2 category-uncategorized tag-codex tag-edge-case tag-featured-image tag-image tag-template">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" class="article-title" itemprop="name">
      事件(Event)
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	Posted on <a href="/2015/05/21/c#-Event/" class="article-date">
	  <time datetime="2015-05-21T15:07:00.000Z" itemprop="datePublished">May 21, 2015</time>
	</a>

      
	<span id="busuanzi_container_page_pv">
	  本文总阅读量<span id="busuanzi_value_page_pv"></span>次
	</span>

    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="事件是什么"><a href="#事件是什么" class="headerlink" title="事件是什么"></a>事件是什么</h2><p>　　事件是对象与对象之间的通信工具。<br>　　事件的很多方面和委托相似，事件就好像是被简化后的针对特殊用途的委托。<a id="more"></a><br><img src="/image/cSharp/cSharp53.png" alt=""><br>　　◆ <strong>触发事件</strong>：调用或者触发事件的术语。当事件被触发时，所有注册到它的方法都会被依次调用。<br>　　◆ <strong>发布者</strong>(publisher)：让事件被其他类或者结构可见并且使用的类或者结构。<br>　　◆ <strong>订阅者</strong>(subscriber)：把事件和发布者关联注册的类或者结构。<br>　　◆ <strong>事件处理程序</strong>(event handler)：注册到事件的方法。可以在事件所在的类或结构中，也可以在不同的类或者结构中。</p>
<h3 id="事件包含私有委托"><a href="#事件包含私有委托" class="headerlink" title="事件包含私有委托"></a>事件包含私有委托</h3><p>　　事件和委托之所以相似，因为事件中包含了一个私有控制的委托：<br>　　■ 事件提供了对它自己包含的这个私有委托的结构化访问(高度控制)。<br>　　■ 事件只能添加、删除和调用事件处理程序(方法)，这点和委托不一样。<br>　　■ 事件被触发时，它调用委托来依次调用调用列表中的方法。<br><img src="/image/cSharp/cSharp54.png" alt=""><br>　　<strong>“+=”、“-=”是事件唯一允许的运算符。</strong></p>
<p>　　下面的图中演示了一个具有计时器事件类的运行结构：<br>　　● 发布者类中包含这一个名为<code>Elapsed</code>的事件。<br>　　● 右边的<code>ClassA</code>和<code>ClassB</code>是两个订阅者类，它们每一个都在<code>Elapsed</code>事件上注册了事件处理程序(也就是<code>TimerHandlerA()</code>和<code>TimerHandlerB()</code>)。<br>　　● 在<code>Elapsed</code>事件内，我们可以看到委托引用了两个事件处理程序。<br>　　● 在发布者类中，除了事件以外，还包含了触发事件的代码。<br><img src="/image/cSharp/cSharp55.png" alt=""></p>
<h3 id="事件的代码组成结构"><a href="#事件的代码组成结构" class="headerlink" title="事件的代码组成结构"></a>事件的代码组成结构</h3><p><img src="/image/cSharp/cSharp56.png" alt=""><br>　　■ 委托类型声明：事件和事件处理程序必须有共同的签名和返回类型，它们通过委托类型声明进行设定。<br>　　■ 事件处理程序声明：这些在订阅者类中的方法(事件处理程序)会在事件触发时被执行。它们不需要独立的的方法，可以是简单的匿名方法或者lambda表达式，只需要执行处理代码即可。<br>　　■ 事件声明：存在于发布者类中的声明，保存并调用事件处理程序。<br>　　■ 事件注册：把事件连接到事件处理程序。<br>　　■ 触发事件的代码：在发布者类中，触发事件的执行，进而导致事件调用事件处理程序。</p>
<h3 id="声明事件"><a href="#声明事件" class="headerlink" title="声明事件"></a>声明事件</h3><p>　　<strong>发布者类必须提供事件和触发事件的代码。</strong><br>　　创建事件比较简单，只需要委托类型和事件名字。<br><img src="/image/cSharp/cSharp57.png" alt=""><br>　　■ Elasped事件被声明在MyTimerClass类(发布者类)中。<br>　　■ Elasped事件接受返回值类型、签名与EventHandler委托类型匹配的事件处理程序。<br>　　■ Elasped事件被public关键字修饰，所以其他的类或者结构都可以在这上面注册事件处理程序。</p>
<p>　　还可以使用逗号分隔声明多个事件：<br>　　<code>public event EventHandler MyEvent1,MyEvent2,MyEvent3;</code></p>
<p>　　还可以使用static关键字修饰，让事件变成静态的。<br>　　<code>public static event EventHandler Elapsed;</code></p>
<h3 id="事件是成员"><a href="#事件是成员" class="headerlink" title="事件是成员"></a>事件是成员</h3><p>　　事件不是类型，而是成员。<br>　　■ 由于事件不是类型，我们不能使用对象创建表达式(new)来创建它的对象。<br>　　■ 由于事件是成员：<br>　　　　□ 它必须声明在类或者结构中，与类或结构中的其他成员一样。<br>　　　　□ 不能再一段可执行代码中声明事件，因为事件是被动触发的。<br>　　■ 事件成员被隐式的自动初始化为null。</p>
<h3 id="委托类型和EventHandler"><a href="#委托类型和EventHandler" class="headerlink" title="委托类型和EventHandler"></a>委托类型和EventHandler</h3><p>　　事件的声明需要委托类型的名字，我们可以声明一个委托类型或者使用BCL(基类库)提供的，如果我们声明一个委托类型，它必须指定注册到事件的事件处理程序的方法签名和返回类型，使用BCL指定为事件使用标准的预定义委托类型，推荐使用<strong>EventHandler</strong>。<br>　　<code>public delegate void EventHandler(object sender,EventArgs e);</code></p>
<h2 id="触发事件"><a href="#触发事件" class="headerlink" title="触发事件"></a>触发事件</h2><p>　　事件需要被动的触发才能够执行，事件成员本身只保存事件被触发时要调用的事件处理程序。<br>　　■ 事件在触发之前可以和<code>null</code>进行比较，从而查看该事件是否包含任何事件处理程序，如果事件为null，则表示该事件没有任何事件处理程序。<br>　　■ 触发事件看起来和调用函数一样：<br>　　　　□ 使用事件名称、后面跟的参数列表包含在圆括号中。<br>　　　　□ 参数列表必须和事件的委托类型相匹配。<br><figure class="highlight gcode"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span><span class="comment">(Elapsed!=null)</span>          <span class="comment">//确认该事件有可用的事件处理程序</span></span><br><span class="line">&#123;</span><br><span class="line">    Elapsed<span class="comment">(source,args)</span>;  <span class="comment">//调用事件</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>　　<strong>把事件声明和触发事件的代码放在一起，便组成了发布者类。</strong><br><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">MyTimerClass</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">event</span> EventHandler Elapsed;    <span class="comment">//声明事件</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">OnOneSecond</span>(<span class="params"><span class="keyword">object</span> source,EventArgs args</span>)  <span class="comment">//调用该方法就会触发事件的执行</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(Elapsed!=<span class="literal">null</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            Elapsed(source,args);  <span class="comment">//发起事件</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p> 　　■ 发布者类有一个做为成员的事件。<br> 　　■ 发布者类包含了触发事件的代码。</p>
<h2 id="订阅事件"><a href="#订阅事件" class="headerlink" title="订阅事件"></a>订阅事件</h2><p> 　　为事件添加处理程序，<strong>处理程序必须有和事件委托一致的返回类型和签名</strong>。<br> 　　■ 使用<strong>+=</strong>为事件增加事件处理程序。<br> 　　■ 方法(事件处理程序)可以是下面的任意一个：<br> 　　　　□ 实例方法<br> 　　　　□ 静态方法<br> 　　　　□ 匿名方法<br> 　　　　□ lambda表达式<br><img src="/image/cSharp/cSharp58.png" alt=""><br>　　和委托一样我们可以使用匿名方法或者lambda表达式尅增加事件处理程序。<br><figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">mc.Elapsed += (<span class="keyword">source</span>,args) =&gt;</span><br><span class="line">    &#123;</span><br><span class="line">      Console.<span class="keyword">WriteLine</span>(<span class="string">"lambda事件处理程序！"</span>);  </span><br><span class="line">    &#125;;</span><br><span class="line">    </span><br><span class="line">mc.Elapsed += delegate(<span class="keyword">source</span>,asgs)</span><br><span class="line">    &#123;</span><br><span class="line">        Console.<span class="keyword">WriteLine</span>(<span class="string">"匿名方法事件处理程序！"</span>);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></p>
<h4 id="代码示例："><a href="#代码示例：" class="headerlink" title="代码示例："></a>代码示例：</h4><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title">Program</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="keyword">string</span>[] args</span>)</span></span><br><span class="line"><span class="function">        </span>&#123;</span><br><span class="line">            ClassA ca = <span class="keyword">new</span> ClassA();</span><br><span class="line">            MyTimerClass mc = <span class="keyword">new</span> MyTimerClass(); <span class="comment">//创建发布者类</span></span><br><span class="line"></span><br><span class="line">            <span class="comment">//增加(订阅)事件处理程序</span></span><br><span class="line">            mc.Elapsed += ca.TimerHandlerA; </span><br><span class="line">            mc.Elapsed += ClassB.TimerHandlerB;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;summary&gt;</span></span></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> 发布者类</span></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;/summary&gt;</span></span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">class</span> <span class="title">MyTimerClass</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">event</span> EventHandler Elapsed;    <span class="comment">//声明事件</span></span><br><span class="line">        <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">OnOneSecond</span>(<span class="params"><span class="keyword">object</span> source, EventArgs args</span>)  <span class="comment">//调用该方法就会触发事件的执行</span></span></span><br><span class="line"><span class="function">        </span>&#123;</span><br><span class="line">            <span class="keyword">if</span> (Elapsed != <span class="literal">null</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                Elapsed(source, args);  <span class="comment">//发起事件</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;summary&gt;</span></span></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> 订阅者类</span></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;/summary&gt;</span></span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">class</span> <span class="title">ClassA</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">TimerHandlerA</span>(<span class="params"><span class="keyword">object</span> obj,EventArgs e</span>)</span></span><br><span class="line"><span class="function">        </span>&#123;</span><br><span class="line">            Console.WriteLine(<span class="string">"ClassA的事件处理程序"</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;summary&gt;</span></span></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> 订阅者类</span></span><br><span class="line">    <span class="comment"><span class="doctag">///</span> <span class="doctag">&lt;/summary&gt;</span></span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">class</span> <span class="title">ClassB</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">TimerHandlerB</span>(<span class="params"><span class="keyword">object</span> obj,EventArgs e</span>)</span></span><br><span class="line"><span class="function">        </span>&#123;</span><br><span class="line">            Console.WriteLine(<span class="string">"ClassB的事件处理程序"</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h3 id="移除事件处理程序"><a href="#移除事件处理程序" class="headerlink" title="移除事件处理程序"></a>移除事件处理程序</h3><p>　　使用<strong>-=</strong>运算符移除一个事件处理程序。<br>　　<code>mc.Elapsed -= ca.TimerHandlerA;   //移除事件处理程序A</code></p>
<h2 id="标准事件的用法"><a href="#标准事件的用法" class="headerlink" title="标准事件的用法"></a>标准事件的用法</h2><p>　　<strong>事件驱动的程序在程序运行时，它可以在任何时候被事件打断。</strong>比如按钮点击事件、定时任务事件，在这些情况发生时，程序会在处理事件后继续其他的事情。<br>　　在c#中winfrom程序广泛的使用了事件，所以最好使用异步编程，.NET框架提供了一个标准的使用模式：<br>　　这个标准模式的根本就是<code>System</code>命名空间声明的<code>EventHandler</code>委托类型：<br>　　■ 第一个参数保存触发该事件的对象的引用，由于是object类型的，所以可以匹配任何类型的实例。<br>　　■ 第二个参数用来保存程序的有关状态信息，比如鼠标坐标等。<br>　　■ 返回值类型是void。</p>
<p>　　<code>EventHandler</code>委托的.Net声明代码：<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System.Runtime.InteropServices;</span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">System</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//</span></span><br><span class="line">    <span class="comment">// 摘要:</span></span><br><span class="line">    <span class="comment">//     表示将处理不包含事件数据的事件的方法。</span></span><br><span class="line">    <span class="comment">//</span></span><br><span class="line">    <span class="comment">// 参数:</span></span><br><span class="line">    <span class="comment">//   sender:</span></span><br><span class="line">    <span class="comment">//     事件源。</span></span><br><span class="line">    <span class="comment">//</span></span><br><span class="line">    <span class="comment">//   e:</span></span><br><span class="line">    <span class="comment">//     不包含事件数据的对象。</span></span><br><span class="line">    [<span class="meta">ComVisible(true)</span>]</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">delegate</span> <span class="keyword">void</span> <span class="title">EventHandler</span>(<span class="params"><span class="keyword">object</span> sender, EventArgs e</span>)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h2 id="事件访问器"><a href="#事件访问器" class="headerlink" title="事件访问器"></a>事件访问器</h2><p>　　<strong>+=、-=运算符时事件唯一允许的运算符</strong>，这两个运算符有着预定义的行为(增加和删除事件处理程序的行为)。<br>　　我们可以编写代码自定义这两个运算符的行为，可以通过为事件定义事件访问器来实现。<br>　　■ 有两个访问器：add和remove。<br>　　■ add用来定义事件的“+=”运算符的执行代码，remove用来定义事件的“-=”运算符的执行代码。<br>　　■ 当事件声明了事件访问器之后，事件包含的私有委托就没有了，如果要增加和移除事件处理程序就需要自己实现。<br>　　■ 事件访问器表现为返回值为void的方法，所以不能使用return语句。<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">event</span> EventHandler Elapsed</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">add</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">//执行+=运算符时的代码</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">remove</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">//执行-=运算符时的代码</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>

      
    </div>
    <footer class="entry-meta entry-footer">
      
	<span class="ico-folder"></span>
    <a class="article-category-link" href="/categories/c/">c#</a>

      
  <span class="ico-tags"></span>
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/c-学习笔记/">c#学习笔记</a></li></ul>

      
        <div id="donation_div"></div>

<script src="/js/vdonate.js"></script>
<script>
var a = new Donate({
  title: '如果觉得我的文章对您有用，请随意打赏。您的支持将鼓励我继续创作!', // 可选参数，打赏标题
  btnText: 'Donate', // 可选参数，打赏按钮文字
  el: document.getElementById('donation_div'),
  wechatImage: '/css/images/wechatPay.png',
  alipayImage: '/css/images/alipay.jpg'
});
</script>
      

      
        
	<section id="comments" class="comment">
	  <div id="disqus_thread">
	  <noscript>Please enable JavaScript to view the <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
	  </div>
	</section>

	<script type="text/javascript">
	var disqus_shortname = 'haijdblog';
	(function(){
	  var dsq = document.createElement('script');
	  dsq.type = 'text/javascript';
	  dsq.async = true;
	  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
	  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
	}());
	(function(){
	  var dsq = document.createElement('script');
	  dsq.type = 'text/javascript';
	  dsq.async = true;
	  dsq.src = '//' + disqus_shortname + '.disqus.com/count.js';
	  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
	}());
	</script>


      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2015/05/22/c#-generic/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          泛型(generic)
        
      </div>
    </a>
  
  
    <a href="/2015/05/20/c#-delegate/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">委托(delegate)</div>
    </a>
  
</nav>

  
</article>

<!-- Table of Contents -->

  <aside id="sidebar">
    <div id="toc" class="toc-article">
    <strong class="toc-title">Contents</strong>
    
      <ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#事件是什么"><span class="nav-number">1.</span> <span class="nav-text">事件是什么</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#事件包含私有委托"><span class="nav-number">1.1.</span> <span class="nav-text">事件包含私有委托</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#事件的代码组成结构"><span class="nav-number">1.2.</span> <span class="nav-text">事件的代码组成结构</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#声明事件"><span class="nav-number">1.3.</span> <span class="nav-text">声明事件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#事件是成员"><span class="nav-number">1.4.</span> <span class="nav-text">事件是成员</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#委托类型和EventHandler"><span class="nav-number">1.5.</span> <span class="nav-text">委托类型和EventHandler</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#触发事件"><span class="nav-number">2.</span> <span class="nav-text">触发事件</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#订阅事件"><span class="nav-number">3.</span> <span class="nav-text">订阅事件</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#代码示例："><span class="nav-number">3.0.1.</span> <span class="nav-text">代码示例：</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#移除事件处理程序"><span class="nav-number">3.1.</span> <span class="nav-text">移除事件处理程序</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#标准事件的用法"><span class="nav-number">4.</span> <span class="nav-text">标准事件的用法</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#事件访问器"><span class="nav-number">5.</span> <span class="nav-text">事件访问器</span></a></li></ol>
    
    </div>
  </aside>
</section>
        
      </div>
      <footer id="footer" class="site-footer">
  

  <div class="clearfix container">
      <div class="site-info">
	      &copy; 2018 haijd All Rights Reserved.
          
            <span id="busuanzi_container_site_uv">
              本站访客数<span id="busuanzi_value_site_uv"></span>人次  
              本站总访问量<span id="busuanzi_value_site_pv"></span>次
            </span>
          
      </div>
      <div class="site-credit">
        Theme by <a href="https://github.com/iTimeTraveler/hexo-theme-hiero" target="_blank">hiero</a>
      </div>
  </div>
</footer>


<!-- min height -->

<script>
    var contentdiv = document.getElementById("content");

    contentdiv.style.minHeight = document.body.offsetHeight - document.getElementById("allheader").offsetHeight - document.getElementById("footer").offsetHeight + "px";
</script>
    </div>
    <!-- <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/categories" class="mobile-nav-link">Categories</a>
  
    <a href="/tags" class="mobile-nav-link">Tags</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
</nav> -->
    

<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/scripts.js"></script>
<script src="/js/bootstrap.js"></script>
<script src="/js/main.js"></script>








	<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
	</script>






  </div>

  <a id="rocket" href="#top" class=""></a>
  <script type="text/javascript" src="/js/totop.js" async=""></script>
</body>
</html>
